package newApi;

import java.util.*;
import static java.util.stream.Collectors.*;

/**
 * 分组与分区
 */
public class StreamTest5 {
    public static void main(String[] args) {
        ArrayList<Student> students = new ArrayList<Student>() {{
            add(new Student("maomao", "english", 25, 80));
            add(new Student("maomao", "chinese", 25, 90));
            add(new Student("keke", "math", 25, 80));
            add(new Student("keke", "english", 25, 80));
            add(new Student("keke", "chinese", 25, 60));
            add(new Student("jiji", "chinese", 25, 70));
            add(new Student("jiji", "english", 25, 90));
        }};

        /**
         * 需求：实现select * from student group by name;
         * 原始写法：1、遍历、获取名称，查看是否在map中存在，不存在创
         * 建List然后把当前元素放入，存在直接放入List，最后返回map
         */
        Map<String, List<Student>> collect1 = students.stream().collect(groupingBy(Student::getName));
        System.out.println(collect1.toString());

        /**
         * 需求：实现select name,count(*) group by name;
         */
        Map<String, Long> collect2 = students.stream().collect(groupingBy(Student::getName, counting()));
        System.out.println(collect2.toString());

        /**
         * 需求：实现select name, avg(score) group by name;
         */
        Map<String, Double> collect3 = students.stream().collect(groupingBy(Student::getName, averagingDouble(Student::getScore)));
        System.out.println(collect3.toString());

        Map<String, Double> collect4 = students.stream().collect(groupingBy(Student::getCourse, averagingDouble(Student::getScore)));
        System.out.println(collect4.toString());

        System.out.println("----分区-----");
        /**
         * 需求：select name,sum(score) from student group by name
         * 班级总平均分，学生个人平均分，各个人平均分低于总平均分的为一个区，高于总平均分的分为一个区
         */
        students.addAll(Arrays.asList(new Student("jiji", "math", 25, 77), new Student("maomao", "math", 25, 87)));

        Double avg = students.stream().collect(averagingDouble(Student::getScore));
        Map<String, Double> studentAvg = students.stream().collect(groupingBy(Student::getName, averagingDouble(Student::getScore)));

        Map<String, List<String>> result = new HashMap<String, List<String>>() {{
            put("up", new ArrayList<>());
            put("down", new ArrayList<>());
        }};
        studentAvg.forEach((name, score) -> {
            if (score > avg) {
                result.get("up").add(name);
            } else {
                result.get("down").add(name);
            }
        });
        System.out.println("班级总平均分：" + avg);
        System.out.println("学生平均分：" + studentAvg);
        System.out.println(result);

        System.out.println("----分区----");
        Map<Boolean, List<Student>> collect = students.stream().collect(partitioningBy(student -> student.getScore() > 80));
        System.out.println(collect);
        System.out.println("--------");

        /**
         * 找出学生中最低分数
         */
        Map<String, Student> collect5 = students.stream().collect(
                groupingBy(Student::getName, collectingAndThen(minBy(Comparator.comparingDouble(Student::getScore)), Optional::get)));
        System.out.println(collect5);

        /**
         * 找出学生中平均分最低的
         */
        Collection<Double> collect6 = students.stream().collect(
                collectingAndThen(
                        groupingBy(
                                Student::getName,
                                collectingAndThen(
                                        averagingDouble(Student::getScore),
                                        item -> Math.floor(item)
                                )
                        ),
                        ittem1 -> ittem1.values()
                )
        );
        System.out.println(collect6);
        System.out.println(Collections.min(collect6));

    }
}
